<?php

/**
 * Tickets controller.
 *
 */
class Tickets_Controller extends SPF_Controller {

   /**
    * The version number of the controller.
    * @var     string
    */
   const VERSION = '1.0.0';

   /**
    * The author of the controller.
    * @var     string
    */
   const AUTHOR  = 'Simon Downes';
   
   /**
    * Constructor
    * @return       void
    */
   public function __construct() {
      /* construct the parent object */
      parent::__construct(__CLASS__);
   }

   /**
    * Destructor
    * @access       public
    * @return       void
    */
   public function __destruct() {
   }

   /**
    * Determines if the current user is permitted to access this controller and perform the requested action
    * @return       boolean   true if access is allowed, false otherwise.
    */
   public function authenticate() {
   
      return (SPF::$session->user != NULL);
      
   } // authenticate
   
   public function index() {
      
      $this->assign('projects', Project::browse_data());
      
      $this->display('index');
      
   } // browse
   
   public function browse( $project_id = NULL ) {
      
      // if no project_id was specified then prompt user to select a project
      if( $project_id == NULL ) {
         SPF::$session->current_project = NULL;
         SPF::redirect('tickets');
      }
      
      $project = new Project();
      $project->fetch( (int) $project_id );
      
      // if project doesn't exist then tell user and prompt them to select one that does
      if( $project_id && !$project->id ) {
         SPF::$session->current_project = NULL;
         SPF::flash(SiTrack::MSG_NOT_FOUND, 'error');
         SPF::redirect('tickets');
      }
      
      // store selected project in the users session
      SPF::$session->current_project = $project->to_array();
      
      // if no filter in session then create a new one
      $filter = new SPF_Filter('ticket');
      if( !$filter->has_conditions() ) {

         // normal options
         $filter->add_condition('ticket_id', 'tickets.id', '=', 'NUMBER');
         $filter->add_condition('title', 'tickets.title', 'CONTAINS', 'STRING');
         $filter->add_condition('ticket_type', 'tickets.ticket_type_id', '=', 'NUMBER', NULL, 'ticket_type');
         $filter->add_condition('ticket_status', 'tickets.ticket_status_id', '=', 'NUMBER', NULL, 'ticket_status');
         $filter->add_condition('assigned_user', 'tickets.assigned_user', '=', 'STRING');
         
         // advanced options
         $filter->add_condition('component', 'tickets.component_id', '=', 'NUMBER', NULL, 'components');
         $filter->add_condition('milestone', 'tickets.milestone_id', '=', 'NUMBER', NULL, 'milestones');
         $filter->add_condition('ticket_priority', 'tickets.ticket_priority_id', '=', 'NUMBER', NULL, 'ticket_priority');
         $filter->add_condition('ticket_severity', 'tickets.ticket_severity_id', '=', 'NUMBER', NULL, 'ticket_severity');
         $filter->add_condition('created_user', 'tickets.created_user', '=', 'STRING');
         $filter->add_condition('include_closed', 'ticket_status.system_type', '!', 'STRING', 'OPEN');
         
         $filter->update();
         
      } // setup filter
      
      // store current filter
      $filter->save();
      
      $this->assign('project_id', $project_id);
      $this->assign('tickets', Ticket::browse_data($project_id, $filter));
      
      $filter_arr = $filter->to_array();
      $filter_arr['conditions']['assigned_user']['options'] = User::lookup_options();
      $filter_arr['conditions']['created_user']['options'] = User::lookup_options();
      $this->assign('filter', $filter_arr);

      $this->display('browse');
      
   } // browse
   
   public function view( $id ) {
      
      // load the requested project object
      $ticket = new Ticket();
      $ticket->fetch( (int) $id );
      
      // if no such ticket then tell the user
      if( !$ticket->id ) {
         SPF::flash(SiTrack::MSG_NOT_FOUND, 'error');
         SPF::redirect('tickets', 'browse', SPF::$session->current_project['id']);
      }
      
      // store selected project in the users session
      $project = new Project();
      $project->fetch( $ticket->project_id );
      SPF::$session->current_project = $project->to_array();
      
      // if form was submitted then update the ticket accordingly
      if( SPF::form_submitted('frm_update_ticket') ) {

         $ticket->ticket_status_id = SPF::post('ticket_status_id');
         $ticket->assigned_user    = SPF::post('assigned_user'); 
         $ticket->validate();
         
         $comment = new SPF_Model('comments');
         $comment->add_validation('details', false, 'alphanumeric', "\r\n". SPF::$config['allowed_chars'] );
         $comment->details = SPF::post('comment_details');
         
         if( $comment->details ) {
            $comment->ticket_id    = $ticket->id;
            $comment->created_user = SPF::$session->user['user_name'];
            $comment->created_date = SPF_Date::mysql_date(NULL, true);
            $comment->validate();
         }
         
         // if no errors then update
         if ( !$ticket->has_errors() && !$comment->has_errors() ) {
            $ticket->update(false);
            $comment->update(false);
            SPF::flash(SiTrack::MSG_SAVED, 'success');
         }
         else {
            $this->assign('comment', $comment->to_array());
         }
         
      } // form submitted

      $this->assign('ticket', $ticket->to_array(true));
      $this->assign('comments', Ticket::get_comments($ticket->id));
      
      $this->assign('ticket_status', SPF::$db->lookup_options('ticket_status', $ticket->ticket_status_id));
      $this->assign('users',  User::lookup_options());
      
      $this->display('view');

   } // view
   
   public function edit( $ticket_id = NULL ) {
      
      // load the requested project object
      $ticket = new Ticket();
      $ticket->fetch( (int) $ticket_id );
      
      // if no project id then use the current project stored in the session
      if( !$ticket->project_id ) {
         if( !SPF::$session->current_project )
            SPF::redirect('tickets');
         else
            $ticket->project_id = (int) SPF::$session->current_project['id'];
      }
      // otherwise update the session project to match the ticket
      else {
         $project = new Project();
         $project->fetch( $ticket->project_id );
         SPF::$session->current_project = $project->to_array();
      }
      
      if ( SPF::form_submitted('frm_ticket') ) {
         
         // run html_entity_decode() against each element in the post array to make sure we're not
         // inserting html into the database. this is only an issue when re-saving existing records
         // as when output to the browser the data will have html entities encoded and we don't want
         // to be saving the encoded entities into the database...
         $data = array_map('html_entity_decode', SPF::post());
         $ticket->from_array($data);
         
         if( !$ticket->created_user || !$ticket->created_date || $ticket->created_date === SPF_Database_MySQL::NULL_DATE ) {
            $ticket->created_user = SPF::$session->user['user_name'];
            $ticket->created_date = SPF_Date::mysql_date(NULL, true);
         }
         
         $ticket->validate();
         
         // if no errors then assign values to dataobject and update
         if ( !$ticket->has_errors() ) {
            $ticket->update(false);
            SPF::flash(SiTrack::MSG_SAVED, 'success');
            SPF::redirect('tickets', 'view', $ticket->id);
         }

      } // is_submitted

      $this->assign('ticket', $ticket->to_array());
      
      $this->assign('projects', SPF::$db->lookup_options('projects', $ticket->project_id));
      $this->assign('components', Project::lookup_options($ticket->project_id, 'components', $ticket->component_id));
      $this->assign('milestones', Project::lookup_options($ticket->project_id, 'milestones', $ticket->milestone_id));
      $this->assign('ticket_type', SPF::$db->lookup_options('ticket_type', $ticket->ticket_type_id));
      $this->assign('ticket_status', SPF::$db->lookup_options('ticket_status', $ticket->ticket_status_id));
      $this->assign('ticket_severity', SPF::$db->lookup_options('ticket_severity', $ticket->ticket_severity_id));
      $this->assign('ticket_priority', SPF::$db->lookup_options('ticket_priority', $ticket->ticket_priority_id));
      $this->assign('users', User::lookup_options($ticket->assigned_user));
      
      $this->display('edit');

   } // edit
   
   public function delete( $ticket_id = NULL ) {
   
      // load the request object
      if( $ticket_id ) {
         $ticket = new Ticket();
         $ticket->delete( (int) $ticket_id );
         SPF::flash(SiTrack::MSG_DELETED, 'success');
      }
      
      SPF::redirect('tickets', 'browse', SPF::$session->current_project['id']);
      
   } // delete
   
   public function delete_comment( $ticket_id = NULL, $comment_id = NULL ) {
      
      $ticket = new Ticket();
      $ticket->fetch( (int) $ticket_id );
      
      if( !$ticket->id ) {
         SPF::flash(SiTrack::MSG_NOT_FOUND, 'error');
         SPF::redirect('tickets', 'browse', SPF::$session->current_project['id']);
      }
      elseif( (int) $comment_id ) {
         $comment = new SPF_Model('comments');
         $comment->delete( (int) $comment_id );
         SPF::flash(SiTrack::MSG_DELETED, 'success');
      }
      
      SPF::redirect('tickets', 'view', $ticket->id);
      
   } // delete_comment
   
   public function quick_search() {
      
      $value = trim(SPF::post('quick_search'));
      
      if( !$value )
         SPF::redirect('tickets', 'browse', SPF::$session->current_project['id']);
      
      // if value is an integer then assume it's a ticket_id
      if( SPF_Validator::is_integer($value) ) {
         SPF::redirect('tickets', 'view', (int) $value);
      }
      
      SPF_Filter::clear_filter('ticket');
      
      // otherwise check if string is a user name and if so then show tickets assigned to that user
      $user = new User();
      if( $user->exists($value) ) {
         SPF::redirect('tickets', 'browse', SPF::$session->current_project['id']. '&assigned_user='. $value);
      }
      
      // otherwise look for the string in the ticket titles
      SPF::redirect('tickets', 'browse', SPF::$session->current_project['id']. '&title='. $value);
      
   } // quick_search
   
   public function export() {
   
      $project_id = SPF::$session->current_project['id'];
      
      // if no filter in session then create a new one
      $filter = new SPF_Filter('ticket');
      
      $tickets = Ticket::export_data($project_id, $filter);
      
      $headers = array('ID', 'Title', 'Project', 'Component', 'Milestone', 'Type', 'Status', 'Priority', 'Severity', 'Assigned To', 'Created By', 'Created Date');
      
      $tmp_file = SPF_APP_DIR. '/cache/'. SPF::$session->user['user_name']. '-export.csv';
      SPF::$db->export_data($tickets, $tmp_file, ',', $headers);
      
      // output CSV content
      header('content-type: text/csv');
      header('content-length: '. filesize($tmp_file));
	   header('content-disposition: attachment; filename=sitrack-export.csv');
      
      echo file_get_contents($tmp_file);
      
      unlink($tmp_file);
      
   } // export
   
} // Tickets_Controller

?>
